package com.itheima.reggie.controller;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.R;
import com.itheima.reggie.domain.Category;
import com.itheima.reggie.domain.Dish;
import com.itheima.reggie.domain.DishFlavor;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.sercice.CategoryService;
import com.itheima.reggie.sercice.DishFlavorService;
import com.itheima.reggie.sercice.DishService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@RequestMapping("/dish")
public class DishController {

    @Autowired
    private DishService dishService;

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private RedisTemplate redisTemplate;

    //分页查询菜品
    @GetMapping("/page")
    public R page(Integer page, Integer pageSize, String name) {

        Page<Dish> pageInfo = new Page<>(page, pageSize);

        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();

        wrapper.like(StringUtils.isNotEmpty(name), Dish::getName, name);

        wrapper.orderByDesc(Dish::getUpdateTime);
        dishService.page(pageInfo, wrapper);

        long total = pageInfo.getTotal();
        Map map = new HashMap();

        map.put("total", (int) total);

        List<Dish> records = pageInfo.getRecords();
        List<DishDto> dishDtos = new ArrayList<>();
        for (Dish record : records) {
            Long categoryId = record.getCategoryId();
            Category category = categoryService.getById(categoryId);
            String categoryName = category.getName();
            DishDto dishDto = new DishDto();
            dishDto.setCategoryName(categoryName);
            BeanUtils.copyProperties(record, dishDto);
            dishDtos.add(dishDto);
        }

        map.put("records", dishDtos);

        return R.success(map);
    }

    //添加菜品
    @CacheEvict(value = "dish", key = "#dishDto.categoryId+'_'+#dishDto.status")
    @PostMapping
    public R saveDish(@RequestBody DishDto dishDto) {

        //接收数据保存到dish表
        dishService.save(dishDto);
        //保存口味数据到dish_flavor表
        List<DishFlavor> flavors = dishDto.getFlavors();

        if (flavors != null && flavors.size() > 0) {
            Long dishId = dishDto.getId();
            for (DishFlavor flavor : flavors) {
                flavor.setDishId(dishId);
            }
            dishFlavorService.saveBatch(flavors);
        }

//      Set keys = redisTemplate.keys("dish_*");
//      redisTemplate.delete(keys);
        //清理某个分类下的菜品缓存
       /* String keys = "dish_" + dishDto.getCategoryId() + "_" + dishDto.getStatus();
        redisTemplate.delete(keys);*/

        return R.success("添加成功");
    }

    //修改前的数据回显
    @GetMapping("/{id}")
    public R getById(@PathVariable Long id) {
        //获取菜品的id
        Dish dish = dishService.getById(id);
        //创建一个dishDto
        DishDto dishDto = new DishDto();
        //吧dish的数据封装copy到dishDto中
        BeanUtils.copyProperties(dish, dishDto);
        //构造条件构造器
        LambdaQueryWrapper<DishFlavor> wrapper = new LambdaQueryWrapper<>();
        //判断条件
        wrapper.eq(DishFlavor::getDishId, dish.getId());
        //查询口味数据
        List<DishFlavor> list = dishFlavorService.list(wrapper);
        //把口味数据设置到dto中
        dishDto.setFlavors(list);

        return R.success(dishDto);
    }

    //修改菜品信息
    //@CacheEvict(value = "dish",key = "#dishDto.categoryId+'_'+#dishDto.status")
    @CacheEvict(value = "dish", allEntries = true)
    @PutMapping
    public R updateDishDto(@RequestBody DishDto dishDto) {
        dishService.updateById(dishDto);
        //获取菜品的id
        Long dishId = dishDto.getId();
        LambdaQueryWrapper<DishFlavor> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DishFlavor::getDishId, dishId);
        dishFlavorService.remove(wrapper);

        List<DishFlavor> flavors = dishDto.getFlavors();
        for (DishFlavor flavor : flavors) {
            flavor.setDishId(dishId);
        }
        dishFlavorService.saveBatch(flavors);
        //清理所有的缓存
//        Set keys = redisTemplate.keys("dish_*");
//        redisTemplate.delete(keys);
        //清理某个分类下的菜品缓存
       /* String keys = "dish_" + dishDto.getCategoryId() + "_" + dishDto.getStatus();
        redisTemplate.delete(keys);
*/
        return R.success("修改成功");
    }

    /**
     * 删除/批量删除
     *
     * @param ids
     * @return
     */

    @CacheEvict(value = "dish", allEntries = true)
    @DeleteMapping
    public R delete(@RequestParam List<Long> ids) {
        LambdaQueryWrapper<DishFlavor> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(DishFlavor::getDishId, ids);
        dishFlavorService.remove(wrapper);
        //遍历需要删除的菜品id
        for (Long id : ids) {
            //根据菜品的id知道菜品分类的id
            Long categoryId = dishService.getById(id).getCategoryId();
            //如果
            if (categoryService.getById(categoryId).getType() != 1) {
                return R.error("当前菜品关联了套餐,不能删除!");
            }
        }
        dishService.removeByIds(ids);
       /* Set keys = redisTemplate.keys("dish_*");
        redisTemplate.delete(keys);*/

        return R.success("删除成功");
    }

    //修改状态
    @CacheEvict(value = "dish", allEntries = true)

    @PostMapping("/status/{status}")
    public R updateStatus(@PathVariable Integer status, @RequestParam List<Long> ids) {
        //遍历ids 得到需要修改的菜品的id
        //设置菜品状态
        //根据id修改
      /*  for (Long id : ids) {
            //Dish dish = dishService.getById(id);
            Dish dish = new Dish();
            dish.setId(id);
            dish.setStatus(status);
            dishService.updateById(dish);
        }*/
        LambdaUpdateWrapper<Dish> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(Dish::getId, status);
        wrapper.in(Dish::getId, ids);
        dishService.update(wrapper);

        return R.success("修改成功");
    }


   /* @GetMapping("/list")
    public R<List<Dish>> getByCategoryId(Dish dish) {

        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(dish.getCategoryId() != null, Dish::getCategoryId, dish.getCategoryId());

        wrapper.eq(Dish::getStatus,1);

        wrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);

        List<Dish> list = dishService.list(wrapper);

        return R.success(list);
    }*/

    /**
     * 根据菜品分类查询
     * @param dish
     * @return
     */
    @GetMapping("/list")
    @Cacheable(value = "dish", key = "#dish.categoryId+'_'+ #dish.status")
    public R getByCategoryId(Dish dish) {
       /* List<DishDto> dishDtos = null;

        String keys = "dish_" + dish.getCategoryId() + "_" + dish.getStatus();

        dishDtos = (List<DishDto>) redisTemplate.opsForValue().get(keys);
       if (dishDtos != null) {
            return R.success(dishDtos);
        }*/
        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(dish.getCategoryId() != null, Dish::getCategoryId, dish.getCategoryId());
        wrapper.eq(Dish::getStatus, 1);
        wrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
        List<Dish> list = dishService.list(wrapper);

        // dishDtos = new ArrayList<>();
        List<DishDto> dishDtos = new ArrayList<>();
        for (Dish dish1 : list) {
            DishDto dishDto = new DishDto();
            BeanUtil.copyProperties(dish1, dishDto);
            LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(DishFlavor::getDishId, dish1.getId());

            List<DishFlavor> dishFlavors = dishFlavorService.list(queryWrapper);
            dishDto.setFlavors(dishFlavors);
            dishDtos.add(dishDto);

        }
        // redisTemplate.opsForValue().set(keys, dishDtos, 60, TimeUnit.MINUTES);

        return R.success(dishDtos);

    }
}
